-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[libc] Add clock_gettime for Darwin #167160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
SchrodingerZhu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the patch! The approach looks good to me except for some minor issues.
SchrodingerZhu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
7b5f4cb to
5733240
Compare
5733240 to
c53542d
Compare
This patch adds support for clock_gettime for Darwin. Darwin syscall 'gettimeofday' is used to query the time from the system. Many headers in llvm-libc-types, namely clockid_t, struct_timespec, struct_timeval, suseconds_t, time_t_32, time_t_64, are modified to include header guards as Darwin has its own implementation of primitive types.
c53542d to
2d5ba2f
Compare
|
@llvm/pr-subscribers-libc Author: Shreeyash Pandey (bojle) ChangesThis patch adds support for clock_gettime for Darwin. Darwin syscall Many headers in llvm-libc-types, namely clockid_t, struct_timespec, Full diff: https://github.com/llvm/llvm-project/pull/167160.diff 16 Files Affected:
diff --git a/libc/include/llvm-libc-macros/darwin/CMakeLists.txt b/libc/include/llvm-libc-macros/darwin/CMakeLists.txt
new file mode 100644
index 0000000000000..ea08c63c00301
--- /dev/null
+++ b/libc/include/llvm-libc-macros/darwin/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_header(
+ time_macros
+ HDR
+ time-macros.h
+)
diff --git a/libc/include/llvm-libc-macros/darwin/time-macros.h b/libc/include/llvm-libc-macros/darwin/time-macros.h
new file mode 100644
index 0000000000000..477dfa8eda85f
--- /dev/null
+++ b/libc/include/llvm-libc-macros/darwin/time-macros.h
@@ -0,0 +1,14 @@
+//===-- Definition of macros from time.h ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
+
+#include <_time.h>
+
+#endif // LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
diff --git a/libc/include/llvm-libc-macros/time-macros.h b/libc/include/llvm-libc-macros/time-macros.h
index 30e0a310a5485..c026df29b1e7f 100644
--- a/libc/include/llvm-libc-macros/time-macros.h
+++ b/libc/include/llvm-libc-macros/time-macros.h
@@ -7,6 +7,8 @@
#include "linux/time-macros.h"
#elif defined(__ELF__)
#include "baremetal/time-macros.h"
+#elif defined(__APPLE__)
+#include "darwin/time-macros.h"
#else
#define CLOCKS_PER_SEC 1000000
#endif
diff --git a/libc/include/llvm-libc-types/clockid_t.h b/libc/include/llvm-libc-types/clockid_t.h
index 4b059599502c4..926948717c664 100644
--- a/libc/include/llvm-libc-types/clockid_t.h
+++ b/libc/include/llvm-libc-types/clockid_t.h
@@ -9,6 +9,12 @@
#ifndef LLVM_LIBC_TYPES_CLOCKID_T_H
#define LLVM_LIBC_TYPES_CLOCKID_T_H
+#if defined(__APPLE__)
+// Darwin provides its own defintion for clockid_t . Use that to prevent
+// redeclaration errors and correctness.
+#include <_time.h>
+#else
typedef int clockid_t;
+#endif // __APPLE__
#endif // LLVM_LIBC_TYPES_CLOCKID_T_H
diff --git a/libc/include/llvm-libc-types/struct_timespec.h b/libc/include/llvm-libc-types/struct_timespec.h
index 28b5a571f6790..8993ecc7db8f0 100644
--- a/libc/include/llvm-libc-types/struct_timespec.h
+++ b/libc/include/llvm-libc-types/struct_timespec.h
@@ -9,6 +9,11 @@
#ifndef LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
#define LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
+#if defined(__APPLE__)
+// Darwin provides its own definition for struct timespec. Include it directly
+// to ensure type compatibility and avoid redefinition errors.
+#include <sys/_types/_timespec.h>
+#else
#include "time_t.h"
struct timespec {
@@ -16,5 +21,6 @@ struct timespec {
/* TODO: BIG_ENDIAN may require padding. */
long tv_nsec; /* Nanoseconds. */
};
+#endif // __APPLE__
#endif // LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
diff --git a/libc/include/llvm-libc-types/struct_timeval.h b/libc/include/llvm-libc-types/struct_timeval.h
index 9595d85a46c8f..41f0b4e92932e 100644
--- a/libc/include/llvm-libc-types/struct_timeval.h
+++ b/libc/include/llvm-libc-types/struct_timeval.h
@@ -12,9 +12,15 @@
#include "suseconds_t.h"
#include "time_t.h"
+#if defined(__APPLE__)
+// Darwin provides its own definition for struct timeval. Include it directly
+// to ensure type compatibility and avoid redefinition errors.
+#include <sys/_types/_timeval.h>
+#else
struct timeval {
time_t tv_sec; // Seconds
suseconds_t tv_usec; // Micro seconds
};
+#endif // __APPLE__
#endif // LLVM_LIBC_TYPES_STRUCT_TIMEVAL_H
diff --git a/libc/include/llvm-libc-types/suseconds_t.h b/libc/include/llvm-libc-types/suseconds_t.h
index 8e926e8401f5c..acc1822cb59e1 100644
--- a/libc/include/llvm-libc-types/suseconds_t.h
+++ b/libc/include/llvm-libc-types/suseconds_t.h
@@ -14,6 +14,12 @@
// types...] and suseconds_t are no greater than the width of type long.
// The kernel expects 64 bit suseconds_t at least on x86_64.
+#if defined(__APPLE__)
+// Darwin provides its own definition for suseconds_t. Include it directly
+// to ensure type compatibility and avoid redefinition errors.
+#include <sys/_types/_suseconds_t.h>
+#else
typedef long suseconds_t;
+#endif // __APPLE__
#endif // LLVM_LIBC_TYPES_SUSECONDS_T_H
diff --git a/libc/include/llvm-libc-types/time_t_32.h b/libc/include/llvm-libc-types/time_t_32.h
index 2c415f6fa9dca..8d7a81e5ce7f7 100644
--- a/libc/include/llvm-libc-types/time_t_32.h
+++ b/libc/include/llvm-libc-types/time_t_32.h
@@ -9,6 +9,12 @@
#ifndef LLVM_LIBC_TYPES_TIME_T_32_H
#define LLVM_LIBC_TYPES_TIME_T_32_H
+#if defined(__APPLE__)
+// Darwin provides its own definition for time_t. Include it directly
+// to ensure type compatibility and avoid redefinition errors.
+#include <sys/_types/_time_t.h>
+#else
typedef __INT32_TYPE__ time_t;
+#endif // __APPLE__
#endif // LLVM_LIBC_TYPES_TIME_T_32_H
diff --git a/libc/include/llvm-libc-types/time_t_64.h b/libc/include/llvm-libc-types/time_t_64.h
index 8f7fd3233646e..c8267abe31289 100644
--- a/libc/include/llvm-libc-types/time_t_64.h
+++ b/libc/include/llvm-libc-types/time_t_64.h
@@ -9,6 +9,12 @@
#ifndef LLVM_LIBC_TYPES_TIME_T_64_H
#define LLVM_LIBC_TYPES_TIME_T_64_H
+#if defined(__APPLE__)
+// Darwin provides its own definition for time_t. Include it directly
+// to ensure type compatibility and avoid redefinition errors.
+#include <sys/_types/_time_t.h>
+#else
typedef __INT64_TYPE__ time_t;
+#endif // __APPLE__
#endif // LLVM_LIBC_TYPES_TIME_T_64_H
diff --git a/libc/src/__support/OSUtil/darwin/exit.cpp b/libc/src/__support/OSUtil/darwin/exit.cpp
index 7439db2ef38b0..a5fa4a7522189 100644
--- a/libc/src/__support/OSUtil/darwin/exit.cpp
+++ b/libc/src/__support/OSUtil/darwin/exit.cpp
@@ -15,9 +15,8 @@ namespace LIBC_NAMESPACE_DECL {
namespace internal {
[[noreturn]] void exit(int status) {
- for (;;) {
+ for (;;)
LIBC_NAMESPACE::syscall_impl<long>(SYS_exit, status);
- }
}
} // namespace internal
diff --git a/libc/src/__support/time/darwin/CMakeLists.txt b/libc/src/__support/time/darwin/CMakeLists.txt
new file mode 100644
index 0000000000000..a06a41289a41c
--- /dev/null
+++ b/libc/src/__support/time/darwin/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_object_library(
+ clock_gettime
+ SRCS
+ clock_gettime.cpp
+ HDRS
+ ../clock_gettime.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.hdr.types.struct_timeval
+ libc.hdr.types.struct_timespec
+)
diff --git a/libc/src/__support/time/darwin/clock_gettime.cpp b/libc/src/__support/time/darwin/clock_gettime.cpp
new file mode 100644
index 0000000000000..aa483aa9a01d2
--- /dev/null
+++ b/libc/src/__support/time/darwin/clock_gettime.cpp
@@ -0,0 +1,42 @@
+//===-- Darwin implementation of internal clock_gettime -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/time/clock_gettime.h"
+#include "hdr/errno_macros.h" // For EINVAL
+#include "hdr/time_macros.h"
+#include "hdr/types/struct_timespec.h"
+#include "hdr/types/struct_timeval.h"
+#include "src/__support/OSUtil/syscall.h" // For syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include <sys/syscall.h> // For SYS_gettimeofday
+#include <sys/time.h> // For struct timezone
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+ErrorOr<int> clock_gettime(clockid_t clockid, struct timespec *ts) {
+ if (clockid != CLOCK_REALTIME)
+ return Error(EINVAL);
+ struct timeval tv;
+ // The second argument to gettimeofday is a timezone pointer
+ // The third argument is mach_absolute_time
+ // Both of these, we don't need here, so they are 0
+ long ret = LIBC_NAMESPACE::syscall_impl<long>(
+ SYS_gettimeofday, reinterpret_cast<long>(&tv), 0, 0);
+ if (ret != 0)
+ // The syscall returns -1 on error and sets errno.
+ return Error(EINVAL);
+
+ ts->tv_sec = tv.tv_sec;
+ ts->tv_nsec = tv.tv_usec * 1000;
+ return 0;
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/darwin/CMakeLists.txt b/libc/src/time/darwin/CMakeLists.txt
new file mode 100644
index 0000000000000..6d68086c72584
--- /dev/null
+++ b/libc/src/time/darwin/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_entrypoint_object(
+ clock_gettime
+ SRCS
+ clock_gettime.cpp
+ HDRS
+ # The public header is part of the parent directory's library.
+ DEPENDS
+ libc.src.__support.time.clock_gettime
+ libc.src.errno.errno
+)
diff --git a/libc/src/time/darwin/clock_gettime.cpp b/libc/src/time/darwin/clock_gettime.cpp
new file mode 100644
index 0000000000000..ecf116bbc5521
--- /dev/null
+++ b/libc/src/time/darwin/clock_gettime.cpp
@@ -0,0 +1,28 @@
+//===---- Darwin implementation of the POSIX clock_gettime function --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===-----------------------------------------------------------------===//
+
+#include "src/time/clock_gettime.h"
+
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/time/clock_gettime.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, clock_gettime,
+ (clockid_t clockid, struct timespec *ts)) {
+ auto result = internal::clock_gettime(clockid, ts);
+ if (!result.has_value()) {
+ libc_errno = result.error();
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/__support/time/darwin/CMakeLists.txt b/libc/test/src/__support/time/darwin/CMakeLists.txt
new file mode 100644
index 0000000000000..ee1247b354173
--- /dev/null
+++ b/libc/test/src/__support/time/darwin/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_libc_test(
+ clock_gettime
+ SUITE libc-support-time-tests
+ SRCS clock_gettime.cpp
+ DEPENDS
+ libc.src.__support.CPP.expected
+ libc.src.__support.time.darwin.clock_gettime
+)
diff --git a/libc/test/src/__support/time/darwin/clock_gettime.cpp b/libc/test/src/__support/time/darwin/clock_gettime.cpp
new file mode 100644
index 0000000000000..d593c5d02744a
--- /dev/null
+++ b/libc/test/src/__support/time/darwin/clock_gettime.cpp
@@ -0,0 +1,20 @@
+//===-- unit tests for darwin's time utilities --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/time/clock_gettime.h"
+#include "src/__support/CPP/expected.h"
+#include "test/UnitTest/Test.h"
+
+template <class T, class E>
+using expected = LIBC_NAMESPACE::cpp::expected<T, E>;
+
+TEST(LlvmLibcSupportDarwinClockGetTime, BasicGetTime) {
+ struct timespec ts;
+ auto result = LIBC_NAMESPACE::internal::clock_gettime(CLOCK_REALTIME, &ts);
+ ASSERT_TRUE(result.has_value());
+}
|
This patch adds support for clock_gettime for Darwin. Darwin syscall
'gettimeofday' is used to query the time from the system.
Many headers in llvm-libc-types, namely clockid_t, struct_timespec,
struct_timeval, suseconds_t, time_t_32, time_t_64, are modified to include
header guards as Darwin has its own implementation of primitive types.